package com.sjtu.service.login;

import com.google.gson.Gson;
import com.sjtu.feign.UserAccountFeign;
import com.sjtu.service.LoginTokenService;
import com.sjtu.web.vo.UserAccountVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

/**
 * nerine
 * 2/7/2020
 */
@Slf4j
@Service
public class LoginTokenServiceImpl implements LoginTokenService {
    @Autowired
    private UserAccountFeign userAccountFeign;
    @Autowired
    private CuratorFramework curatorFramework;
    @Autowired
    private Gson gson;

    public static final String ZK_PATH = "/sjtu/login-token";
    public static final int TOKEN_EXPIRE_SECONDS = 60 * 30;

    @Override
    public UserAccountVo findByUserId(String userId) {
        return userAccountFeign.findByUserId(userId).getData();
    }

    @Override
    public String generateToken(String userId) {
        try {
            String path = ZK_PATH + "/" + userId;
            LoginToken loginToken = new LoginToken();
            loginToken.setToken(UUID.randomUUID().toString());
            loginToken.setCreatedDate(new Date());
            loginToken.setExpiredSeconds(TOKEN_EXPIRE_SECONDS);

            byte[] data = (gson.toJson(loginToken)).getBytes();
            curatorFramework.create()
                    .orSetData()
                    .creatingParentContainersIfNeeded()
                    .withMode(CreateMode.EPHEMERAL)
                    .forPath(path, data);
            return loginToken.getToken();
        }catch (Exception e) {
            log.error("error in generateToken, userId is: " + userId, e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean checkTokenIsValid(String userId, String token) {
        if(StringUtils.isBlank(userId) || StringUtils.isBlank(token)) {
            return false;
        }
        try {
            String path = ZK_PATH + "/" + userId;
            String json = new String(curatorFramework.getData().forPath(path));
            if(json == null) {
                return false;
            }
            LoginToken loginToken = gson.fromJson(json, LoginToken.class);
            return !loginToken.isExpired(new Date());
        }catch (Exception e) {
            log.error("error in checkTokenIsValid, userId is: " + userId, e);
            return false;
        }
    }
}
